﻿using System;
using System.ServiceModel;
using System.Web;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;
using Kaesoft.Hospedaje.Entities;
using System.ServiceModel.Channels;

namespace Kaesoft.Hospedaje.Business
{
    public static class ServerCache
    {
        #region Variables
        /// <summary>
        /// Caché manager
        /// </summary>
        public static readonly ICacheManager ServiceCache = CacheFactory.GetCacheManager();
        #endregion

        #region Metodos Publicos
        /// <summary>
        /// Obtiene las credenciales de usuario
        /// </summary>
        /// <returns>Nombre del usuario</returns>
        public static string ObtenerIdentidad()
        {
            try
            {
                const string WS_NAMESPACE = "urn:LOBApplicationFramework.Security";

                MessageHeaders headers = OperationContext.Current.IncomingMessageHeaders;
                string customParameter = headers.GetHeader<string>(typeof(string).Name, WS_NAMESPACE);

                return customParameter;
            }
            catch
            {
                return HttpContext.Current.Request.LogonUserIdentity.Name;
            }

        }

        /// <summary>
        /// Graba el usuario autenticado en caché
        /// </summary>
        /// <param name="logOn">Usuario</param>
        public static void GrabarUsuarioAutenticado(Usuario logOn)
        {
            ServiceCache.Add(ObtenerClaveDeAutenticacion(), logOn, CacheItemPriority.Normal, null, new SlidingTime(TimeSpan.FromHours(24)));
        }

        /// <summary>
        /// Eliminar de caché el login
        /// </summary>
        /// <param name="logOn">Usuario</param>
        public static void EliminarUsuarioAutenticado(Usuario logOn)
        {
            string loginKey = ObtenerClaveDeAutenticacion();
            Usuario login = ServiceCache.GetData(loginKey) as Usuario;
            if (login != null)
                ServiceCache.Remove(loginKey);
            ServiceCache.Add(loginKey, logOn, CacheItemPriority.Normal, null, new SlidingTime(TimeSpan.FromHours(24)));
        }

        /// <summary>
        /// Obtener el login desde cache
        /// </summary>
        /// <returns>Usuario</returns>
        public static Usuario ObtenerUsuarioAutenticado()
        {
            string loginKey = ObtenerClaveDeAutenticacion();
            Usuario login = ServiceCache.GetData(loginKey) as Usuario;

            if (login == null)
                throw new FaultException(new FaultReason(@"La sesión ha expirado"));
            return login;
        }

        /// <summary>
        /// Grabar datos de auditoria en caché
        /// </summary>
        /// <param name="auditData">Datos de auditoría</param>
        public static void GrabarDatosAuditoria(AuditData auditData)
        {
            ServiceCache.Add(ObtenerClaveAuditoria(), auditData, CacheItemPriority.Normal, null, new SlidingTime(TimeSpan.FromHours(24)));
        }

        /// <summary>
        /// Obtener desde caché los datos de auditoría
        /// </summary>
        /// <returns>Datos de auditoría</returns>
        public static AuditData ObtenerDatosAuditoria()
        {
            AuditData data = ServiceCache.GetData(ObtenerClaveAuditoria()) as AuditData;
            if (data == null)
                throw new FaultException(@"Session expired");
            return data;
        }

        /// <summary>
        /// Graba en cache el objeto de tipo T
        /// </summary>
        /// <typeparam name="T">Tipo de dato del objeto</typeparam>
        /// <param name="key">Clave</param>
        /// <param name="objeto">Objeto</param>
        public static void GrabarObjetoCache<T>(string key, T objeto)
        {
            ServiceCache.Add(key, objeto, CacheItemPriority.Normal, null, new SlidingTime(TimeSpan.FromHours(24)));
        }


        public static T ObtenerDatosObjetoCache<T>(string key)
        {
            T data = (T)ServiceCache.GetData(key);
            return data;
        }
        #endregion

        #region Metodos Privados
        /// <summary>
        /// Obtiene la clave donde se almacena la identidad en caché
        /// </summary>
        /// <returns>Clave</returns>
        private static string ObtenerClaveDeAutenticacion()
        {
            return string.Concat("_LOGIN_KEY", ObtenerIdentidad());
        }

        /// <summary>
        /// Obtiene la clave en caché de la información de auditoría
        /// </summary>
        /// <returns></returns>
        private static string ObtenerClaveAuditoria()
        {
            return string.Concat("_AUDITDATA_KEY", ObtenerIdentidad());
        }
        #endregion
    }
}